package com.controller;

import com.alibaba.fastjson.JSONObject;
import com.domain.User;
import com.domain.UserInfo;
import com.dto.JsonResponse;
import com.dto.PageResult;
import com.service.impl.UserFollowServiceImpl;
import com.service.impl.UserServiceImpl;
import com.support.UserSupport;
import com.util.RSAUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;

@RequestMapping("/user")
@RestController
public class UserApi {

    @Autowired
    private UserSupport userSupport;

    @Autowired
    private UserServiceImpl userServiceImpl;

    @Autowired
    private UserFollowServiceImpl userFollowServiceImpl;

    /**
     * 返回RSA公钥给前端
     */
    @GetMapping("/rsa-pks")
    public JsonResponse<String> getRsaPublicKey() {
        String pk = RSAUtil.getPublicKeyStr();
        System.out.println("执行了获取公钥的方法");
        return new JsonResponse<>(pk);
    }

    /**
     * 注册
     */
    @PostMapping("/register")
    public JsonResponse<String> register(@RequestBody User user) {
        userServiceImpl.register(user);
        return JsonResponse.success();
    }

    /**
     * 用户登录，返回令牌，令牌在用户使用其他功能时派的上用场
     */
    @PostMapping("/login")
    public JsonResponse<String> login(@RequestBody User user) throws Exception {
        String token = userServiceImpl.login(user);
        return new JsonResponse<>(token);
    }

    @PostMapping("/updateUser")
    public JsonResponse<String> updateUser(@RequestBody User user) throws Exception {
        Long userId = userSupport.getCurrentUserId();
        user.setId(userId);
        userServiceImpl.updateUsers(user);
        return JsonResponse.success();
    }

    /**
     * 获取用户的所有信息
     */
    @GetMapping("/getUserInfo")
    public JsonResponse<User> getUserInfo() {
        Long userId = userSupport.getCurrentUserId();
        User user = userServiceImpl.getUserAndInfoByUserId(userId);
        return new JsonResponse<>(user);
    }

    /**
     * 修改用户的基本信息
     */
    @PutMapping("/updateUserInfo")
    public JsonResponse<String> updateUserInfo(@RequestBody UserInfo userInfo) {
        Long userId = userSupport.getCurrentUserId();
        userInfo.setUserId(userId);
        userServiceImpl.updateUserInfos(userInfo);
        return JsonResponse.success();
    }

    /**
     * 分页查询本用户的关注列表
     */
    @GetMapping("/pageListUserInfo")
    public JsonResponse<PageResult<UserInfo>> pageListUserInfo(@RequestParam Integer pageNum,
                                                               @RequestParam Integer pageSize,
                                                               String nick) {
        Long userId = userSupport.getCurrentUserId();
        JSONObject params = new JSONObject();
        params.put("pageNum", pageNum);
        params.put("pageSum", pageSize);
        params.put("nick", nick);
        params.put("userId", userId);
        PageResult<UserInfo> result = userServiceImpl.pageListUserInfos(params);
        return new JsonResponse<>(result);
    }


    /**
     * 双令牌登录
     */
    @PostMapping("/user-dts")
    public JsonResponse<Map<String, Object>> loginForDts(@RequestBody User user) throws Exception {
        Map<String, Object> map = userServiceImpl.loginForDts(user);
        return new JsonResponse<>(map);
    }

    /**
     * 退出登录（删除长时令牌）
     */
    @DeleteMapping("/refresh-tokens")
    public JsonResponse<String> logout(HttpServletRequest request) {
        String refreshToken = request.getHeader("refreshToken");
        Long userId = userSupport.getCurrentUserId();
        userServiceImpl.logout(refreshToken, userId);
        return JsonResponse.success();
    }

    /**
     * 刷新短时token
     * 单令牌登录：如果用户要访问接口，此时token过期，前端会返回token过期的提示，提醒用户要重新登陆，体验不好
     * 双令牌登录：如果用户要访问接口，此时短时令牌过期，前端不会马上返回token过期的提示，而是会向后端请求新的短时令牌
     * 后端会从数据库中根据长时令牌获取userId，再根据userId生成新的短时令牌并返回
     * 如果长时令牌也过期了，那才需要重新登陆
     */
    @DeleteMapping("/access-tokens")
    public JsonResponse<String> refreshAccessToken(HttpServletRequest request) throws Exception {
        String refreshToken = request.getHeader("refreshToken");
        String accessToken = userServiceImpl.refreshAccessToken(refreshToken);
        return new JsonResponse<>(accessToken);
    }
}
